/*
 * AdvancedQuery.java
 *
 * Created on September 8, 2007, 8:35 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package org.adl.registry.website.lucene;

import java.util.ArrayList;
import java.util.Iterator;

/**
 *
 * @author Jacob
 */
public class AdvancedQuery extends Query
{
    public static final String ALL_FIELD = "all";
    public static final String ANY_FIELD = "any";
    public static final String EXACT_FIELD = "exact";
    public static final String WITHOUT_FIELD = "without";
    public static final String REPOSITORY_FIELD = "repository";
    public static final String CONTRIBUTOR_FIELD = "contributor";
    public static final String STATUS_FIELD = "status";
    public static final String CONTENT_IDENTIFIER_FIELD = "content";
    public static final String METADATA_IDENTIFIER_FIELD = "metadata";
    
    private ArrayList<String> mLimitingFields;
    
    /** Creates a new instance of AdvancedQuery */
    public AdvancedQuery()
    {
        this.mLimitingFields = new ArrayList<String>();
    }
    
    public void addLimitingField(String field)
    {
        this.mLimitingFields.add(field);
    }
    
    public void addAllTermQueryElement(String value)
    {
        ArrayList<QueryElement> elements = super.getQueryElements();
        
        Iterator<QueryElement> iterator = elements.iterator();
        while (iterator.hasNext())
        {
            QueryElement e = iterator.next();
            
            if (e instanceof AllTermQueryElement)
            {
                //TODO: throw exception
            }
        }
        
        AllTermQueryElement element = new AllTermQueryElement(value);
        
        super.addElement(element);
    }
    
    public void addAnyTermQueryElement(String value)
    {
        ArrayList<QueryElement> elements = super.getQueryElements();
        
        Iterator<QueryElement> iterator = elements.iterator();
        while (iterator.hasNext())
        {
            QueryElement e = iterator.next();
            
            if (e instanceof AnyTermQueryElement)
            {
                //TODO: throw exception
            }
        }
        
        AnyTermQueryElement element = new AnyTermQueryElement(value);
        
        super.addElement(element);
    }
    
    public void addContentIdentifierQueryElement(String value)
    {
        ArrayList<QueryElement> elements = super.getQueryElements();
        
        Iterator<QueryElement> iterator = elements.iterator();
        while (iterator.hasNext())
        {
            QueryElement e = iterator.next();
            
            if (e instanceof ContentIdentifierQueryElement)
            {
                //TODO: throw exception
            }
        }
        
        ContentIdentifierQueryElement element = new ContentIdentifierQueryElement(value);
        
        super.addElement(element);
    }
    
    public void addContentStatusQueryElement(String value)
    {
        ContentStatusQueryElement element = null;
        
        ArrayList<QueryElement> elements = super.getQueryElements();
        
        Iterator<QueryElement> iterator = elements.iterator();
        while (iterator.hasNext())
        {
            QueryElement e = iterator.next();
            
            if (e instanceof ContentStatusQueryElement)
            {
                element = (ContentStatusQueryElement)e;
                
                break;
            }
        }
        
        if (element == null)
        {
            element = new ContentStatusQueryElement();
            
            super.addElement(element);
        }
        
        element.addStatus(value);
    }
    
    public void addContributorQueryElement(String role, String value)
    {
        ContributorQueryElement element = null;
        
        ArrayList<QueryElement> elements = super.getQueryElements();
        
        Iterator<QueryElement> iterator = elements.iterator();
        while (iterator.hasNext())
        {
            QueryElement e = iterator.next();
            
            if (e instanceof ContributorQueryElement)
            {
                element = (ContributorQueryElement)e;
                
                break;
            }
        }
        
        if (element == null)
        {
            element = new ContributorQueryElement();
            
            super.addElement(element);
        }
        
        element.addContributionPair(role, value);
    }
    
    public void addExcludedTermsQueryElement(String value)
    {
        ArrayList<QueryElement> elements = super.getQueryElements();
        
        Iterator<QueryElement> iterator = elements.iterator();
        while (iterator.hasNext())
        {
            QueryElement e = iterator.next();
            
            if (e instanceof ExcludeAllQueryElement)
            {
                //TODO: throw exception
            }
        }
        
        ExcludeAllQueryElement element = new ExcludeAllQueryElement(value);
        
        super.addElement(element);
    }
    
    public void addMetadataIdentifierQueryElement(String value)
    {
        ArrayList<QueryElement> elements = super.getQueryElements();
        
        Iterator<QueryElement> iterator = elements.iterator();
        while (iterator.hasNext())
        {
            QueryElement e = iterator.next();
            
            if (e instanceof MetadataIdentifierQueryElement)
            {
                //TODO: throw exception
            }
        }
        
        MetadataIdentifierQueryElement element = new MetadataIdentifierQueryElement(value);
        
        super.addElement(element);
    }
    
    public void addPhraseQueryElement(String value)
    {
        ArrayList<QueryElement> elements = super.getQueryElements();
        
        Iterator<QueryElement> iterator = elements.iterator();
        while (iterator.hasNext())
        {
            QueryElement e = iterator.next();
            
            if (e instanceof PhraseQueryElement)
            {
                //TODO: throw exception
            }
        }
        
        PhraseQueryElement element = new PhraseQueryElement(value);
        
        super.addElement(element);
    }
    
    public void addRepositoryQueryElement(String value)
    {
        ArrayList<QueryElement> elements = super.getQueryElements();
        
        Iterator<QueryElement> iterator = elements.iterator();
        while (iterator.hasNext())
        {
            QueryElement e = iterator.next();
            
            if (e instanceof RepositoryQueryElement)
            {
                //TODO: throw exception
            }
        }
        
        RepositoryQueryElement element = new RepositoryQueryElement(value);
        
        super.addElement(element);
    }
    
    public String toString()
    {
        StringBuilder b = new StringBuilder();
        
        int counter = 0;
        
        ArrayList<QueryElement> otherFields = new ArrayList<QueryElement>();
        
        ArrayList<QueryElement> elements =  super.getQueryElements();
        
        Iterator<QueryElement> iterator = elements.iterator();
        
        while (iterator.hasNext())
        {
            String prefix = "";
            
            QueryElement element = iterator.next();
            
            if (counter > 0)
            {
                //TODO: get default operator
                
                b.append(" AND ");
            }
            
            if (element instanceof AllTermQueryElement)
            {
                b.append("(" + element.toString() + ")");
            }
            else if (element instanceof AnyTermQueryElement)
            {
                b.append("(" + element.toString() + ")");
            }
            else if (element instanceof ExcludeAllQueryElement)
            {
                b.append(element.toString());
            }
            else if (element instanceof PhraseQueryElement)
            {
                b.append(element.toString());
            }
            else if (element instanceof RepositoryQueryElement)
            {
                b.append("(" + element.toString() + ")");
            }
            else if (element instanceof ContributorQueryElement)
            {
                otherFields.add(element);
            }
            else if (element instanceof ContentStatusQueryElement)
            {
                otherFields.add(element);
            }
            else if (element instanceof ContentIdentifierQueryElement)
            {
                b.append(element.toString());
            }
            else if (element instanceof MetadataIdentifierQueryElement)
            {
                b.append(element.toString());
            }
            
            counter++;
        }
        
        if (this.mLimitingFields.size() > 0)
        {
            StringBuilder temp = b;
            
            b = new StringBuilder();
            
            int fieldCounter = 0;
            
            Iterator<String> limittingFieldIterator = this.mLimitingFields.iterator();
            
            while (limittingFieldIterator.hasNext())
            {
                String limitingField = limittingFieldIterator.next();
                
                if (fieldCounter == 0)
                {
                    String formattedField = limitingField + ":(" + temp.toString() + ")";
                    
                    b.append(formattedField);
                }
                else
                {
                    //TODO: get default operator
                    String formattedField = " AND " + limitingField + ":(" + temp.toString() + ")";
                    
                    b.append(formattedField);
                }
            }
        }
        
        if (otherFields.size() > 0)
        {
            Iterator otherFieldIterator = otherFields.iterator();
            
            while(otherFieldIterator.hasNext())
            {
                //TODO: handle instance when no other fields are provided.
                QueryElement otherElement = (QueryElement)otherFieldIterator.next();
                
                b.append(otherElement.toString());
            }
        }
        
        return b.toString();
    }
    
}
